# LuckPay Web Manage System
#
# Copyright (c) 2016 Lucky Byte, Inc.
#
express = require 'express'
fs      = require 'fs'
readline = require 'readline'
router = express.Router()
module.exports = router


stat_file_size = (name) ->
    path = settings.logs_dir + "/" + name
    return null if not fs.existsSync(path)

    stats = fs.statSync(path)
    return null if not stats.isFile()

    if stats.size > 1024 * 1024
        return Math.round(stats.size / 1024 / 1024 * 100) / 100 + 'M'
    return Math.round(stats.size / 1024 * 100) / 100 + 'K'


readlines = (name, start) ->
    return null if not fs.existsSync(name)

    result = []
    reader = readline.createInterface
        input: fs.createReadStream(name)

    reader.on 'line', (line) ->
        result.add line


router.use (req, res, next) ->
    # 计算各文件 size
    res.locals.pos091_size  = stat_file_size 'luckpay_091.log'
    res.locals.servlet_size = stat_file_size 'luckpay_servlet.log'
    res.locals.sched_size   = stat_file_size 'luckpay_sched.log'
    res.locals.tpdu_size    = stat_file_size 'tpdu.log'
    res.locals.jdbc_size    = stat_file_size 'jdbc.log'
    next()


router.get '/', (req, res, next) ->
    res.redirect '/logs/luckpay_091'


get_level = (str) ->
    switch str
        when 'FATAL' then return 1
        when 'ERROR' then return 2
        when 'WARN'  then return 3
        when 'INFO'  then return 4
        when 'DEBUG' then return 5
        when 'TRACE' then return 6
        else return null

router.all '/:path', (req, res, next) ->
    filepath = settings.logs_dir + "/" + req.params.path + ".log"
    if not fs.existsSync(filepath)
        return next new Error('日志文件 ' + filepath + ' 不存在.')

    # 设置 form 的 action
    res.locals.path = req.params.path

    res.locals.keyword = req.body.keyword or ''
    res.locals.level = req.body.level
    level_int = get_level(res.locals.level) or 99
    res.locals.start_no = parseInt(req.body.start_no) or 0
    res.locals.max_lines = parseInt(req.body.max_lines) or 500

    regex = /^(.+) \[(.+) ([a-zA-Z0-9_]+)\] ([a-zA-Z]+) - (.*)$/

    lines = []
    reader = readline.createInterface
        input: fs.createReadStream(filepath)

    line_no = 0
    last_level = 'INFO'

    reader.on 'line', (line) ->
        line_no +=  1

        # 指定起始行号时，略过起始行之前的内容
        return if res.locals.start_no > 0 and line_no < res.locals.start_no

        # 匹配关键字
        if res.locals.keyword.length > 0
            return if line.indexOf(res.locals.keyword) < 0

        log_line = { line_no: line_no, level: last_level }
        matchs = regex.exec line
        if matchs
            log_line.time    = matchs[1]
            log_line.thread  = matchs[2]
            log_line.logger  = matchs[3]
            log_line.level   = matchs[4]
            log_line.message = matchs[5]

            # 保留当前的级别，因为下一行有可能是这一行的延续
            last_level = log_line.level
        else
            log_line.message = line

        # 忽略级别不够的日志
        if (get_level(log_line.level) or 1) <= level_int
            lines.push log_line

        # 在达到预期的行数时，如果指定了起始行号，则处理完毕，否则继续读，但是丢弃最早超出的数据
        if lines.length >= res.locals.max_lines
            if res.locals.start_no > 0
                return reader.close()
            lines.shift()

    reader.on 'close', ->
        res.render 'logs', lines: lines
